/**
 * 
 */
package com.vision.core.sv.serv.rpc;

import static com.vision.core.cm.data.AdminPermissions.CreateCompany;
import static com.vision.core.cm.data.AdminPermissions.DeleteCompany;
import static com.vision.core.cm.data.AdminPermissions.UpdateCompany;
import static com.vision.core.cm.data.AdminPermissions.ViewCompany;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.vision.core.cm.data.Domain;
import com.vision.core.cm.db.data.Company;
import com.vision.core.cm.db.data.CompanyGroup;
import com.vision.core.cm.exception.DataNotFoundException;
import com.vision.core.cm.exception.HasReferenceException;
import com.vision.core.cm.exception.RpcException;
import com.vision.core.cm.serv.rpc.CompanyGroupService;
import com.vision.core.sv.db.mgr.IDataManager;
import com.vision.core.sv.db.mgr.ISimpleCriteria;
import com.vision.core.sv.db.mgr.SimpleCriteria;

/**
 * @author Mark
 *
 */
@Service("company_groups")
public class CompanyGroupServiceImpl extends AbstractServiceImpl<CompanyGroup> implements CompanyGroupService {

	private static final long serialVersionUID = 1L;
	
	private static final Logger log = LoggerFactory.getLogger(CompanyGroupServiceImpl.class);
	
	private static final String MESSAGE_NOT_FOUND = "The Company Group does not exist.";
	
	public CompanyGroupServiceImpl() {
		initGilead();
	}

	@Autowired
	@Qualifier("companyGroupManager")
	@Override
	public void setDataManager(IDataManager<CompanyGroup> dataManager) {
		super.setDataManager(dataManager);
	}
	
	/*@ SuppressWarnings("unused")
	@ Autowired
	@ Qualifier("salesInvoiceManager")
	private IDataManager<SalesInvoice> salesInvoiceManager;
	*/

	@Override
	protected Domain getDomain() {
		return Domain.COMPANY_GROUP;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<CompanyGroup> getGroups(Company company) throws RpcException {
		checkPermissions(ViewCompany);
		
		ISimpleCriteria crit = SimpleCriteria.forClass(CompanyGroup.class);
		crit.eq("company.id", company.getId());
		crit.asc("code");
		
		return getDataManager().getTemplate().findByCriteria(crit.getDetached());
	}
	
	@Override
	public List<CompanyGroup> getAll() throws RpcException {
		checkPermissions(ViewCompany);
		return super.getAll();
	}
	
	@Transactional
	@Override
	public CompanyGroup create(CompanyGroup companyGroup) throws RpcException {
		checkPermissions(CreateCompany);

		CompanyGroup existing = checkExisting(companyGroup);
		if (existing != null)
		{
			log.error("Company group code already exists: {}", companyGroup.getCode());
			throw new RpcException("Company group code already exists.");
		}
		
		CompanyGroup result = super.create(companyGroup);
		
		logCreate(result);
		
		return result;
	}
	
	@Transactional
	@Override
	public CompanyGroup update(CompanyGroup companyGroup) throws RpcException {
		checkPermissions(UpdateCompany);
		CompanyGroup existing = checkExisting(companyGroup);
		if (existing == null)
			throw new DataNotFoundException(MESSAGE_NOT_FOUND);
		
		log.debug("Updating company group: {}", companyGroup.getCode());

		CompanyGroup result = super.update(companyGroup);
		
		logUpdate(existing, result);
		
		return result;
	}
	
	@Transactional
	@Override
	public CompanyGroup delete(CompanyGroup companyGroup) throws RpcException {
		checkPermissions(DeleteCompany);
		CompanyGroup existing = checkExisting(companyGroup);
		if (existing == null)
			throw new DataNotFoundException(MESSAGE_NOT_FOUND);
		
		log.debug("Deleting company group: {}", existing.getCode());
		
		if (hasReference(companyGroup))
			throw new HasReferenceException("CompanyGroup " + companyGroup.getCode() + " is being used and referred to by sales invoice.");
		
		CompanyGroup result = super.delete(existing);
		
		logDelete(result);
		
		return result;
	}
	
	// Helpers *****************************************************************
	
	private boolean hasReference(CompanyGroup companyGroup) {
		// TODO add checking for reference sales invoice
		return false;
	}

	protected CompanyGroup checkExisting(CompanyGroup companyGroup) {
		CompanyGroup existing = getDataManager().getById(companyGroup.getCode());
		return existing;
	}
	
}
